package net.openl10n.mdf;

import java.util.List;

import net.openl10n.document.api.IDocument;
import net.openl10n.mdf.immutable.Immutable;

import com.google.common.collect.ImmutableList;

public class Document implements IDocument, Immutable{

	private final DocumentId id;
	private final Long version;
	private final ImmutableList<PartId> parts;
	
	private final int hashCode;
	
	public Document(DocumentId id, Long version, List<PartId> parts){
		if(id == null)
			throw new IllegalArgumentException("id cannot be null.");
		this.id = id;
		if(version == null)
			throw new IllegalArgumentException("version cannot be null.");
		this.version = version;

		if(parts == null)
			throw new IllegalArgumentException("parts cannot be null.");
		if(parts instanceof ImmutableList<?>)
			this.parts = (ImmutableList<PartId>) parts;
		else
			this.parts = ImmutableList.copyOf(parts);
		
		this.hashCode = generateHashCode();
	}
	
	@Override
	public final DocumentId getId() {
		return id;
	}
	
	@Override
	public final Long getVersion() {
		return version;
	}

	@Override
	public final ImmutableList<PartId> getParts() {
		return parts;
	}
	
	@Override
	public final boolean equals(Object obj) {
		if(obj == null) return false;
		if( !(obj instanceof Document) ) return false;
		Document other = (Document) obj;
		return ( other.id.equals(id) 
				&& other.parts.equals(parts) 
				&& other.version.equals(version) );
	}

	@Override
	public final int hashCode() {
		return hashCode;
	}
	
	private int generateHashCode(){
	    int hash = 1;
	    hash = hash * 31 + id.hashCode();
	    hash = hash * 31 + version.hashCode();
	    hash = hash * 31 + parts.hashCode();
	    return hash;
	}
}
